<template>
	<view class="gd-map-main">
		<view class="map-container"  :class="{'driving-container': recordType==='1'}" >
			<view
				id="container" 
				class="map" 
				:prop="routeInfo"
				:change:prop="mapModel.onChange" 
				:isPhoneGps="isPhoneGps" 
				:change:isPhoneGps="mapModel.onIsPhoneGpsChange"
			>
			</view>
		</view>
		
		<view class="locate-img-wrap" @click="mapModel.currlocate">
			<image class="locate-img" mode="widthFix" src="https://a.amap.com/jsapi/static/image/plugin/locate.png" />
		</view>

	</view>
</template>

<script>
	import dayjs from "dayjs"
	export default {
		props: {
			routeInfo: {
				type: Object,
				default: () => ({})
			},
			isPhoneGps: {
				type: Boolean,
				default: false
			},
			recordType: {
				type: String,
				default: "0"
			},
			logContent: {
				type: Object,
				default: () => ({})
			},
		},
		watch: {
			recordType: {
				deep: true,
				immediate: true,
				handler(val) {
					// this.recordType = val
				}
			}
		},
		data() {
			return {}
		},
		methods: {
			upladPhoneGps(data) {
				this.$emit('upladPhoneGps', data)
			},
			uploadPlanPoint(data) {
				this.$emit('uploadPlanPoint', data)
			},
			saveErrLog(logObj) {
				try {
					let logContent = {
						...this.logContent,
						...logObj
					}
					const params = {
					  logContent: JSON.stringify(logContent),
					  logPosition: 'test-drive',
					  module: '试乘试驾地图',
					  operateTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
					}
			
					console.log("他喵的======>>>", logContent)
			
				} catch (error) {
					console.log(error)
				}
			}
		}
	}
</script> 

<script module="mapModel" lang="renderjs">
	
	import {cloneDeep,chunk} from "lodash";
	import dayjs from "dayjs"
	import AMapLoader from '@amap/amap-jsapi-loader';
	window._AMapSecurityConfig = {
		securityJsCode: '3204765d4469529c3b56910a94bff975' //你的安全秘钥
	}
	let lastTimestamp = 0
	
	export default {
		data() {
			return {
				map: null,
				AMap: null,
				graspRoad: null,
				carMark: null,
				startMark: null,
				mapData: {},
				routeExtList: [],
				rideRouteList: [],
				driveRouteList: [],
				planRouteList: [],
				moveList: [],
				moveIndex: 0,
				ridePolyline: null,
				drivePolyline: null,
				passedPolyline: null,
				timer: null,
				routeInfo1: {
					rideRouteList: [],
					driveRouteList: [],
				},
				geolocation: null,
				geolocationTimer: null,
				watchId: null,
				ownerInstance: null,
				duration: 500,
				lastMoveArr: [],
				lastLocatePoint: {},
				returnIndex: 0,
				isStartLocalTool: false,
				lastCenterPoint: [],
				initTrackMarkTool: false,
				markerList: [],
				
				movePath: [],
				moveStep: 0
			}
		},
		computed: {
			startLocalTool() {
				console.log(this.isStartLocalTool);
				console.log(this.AMap);
				let tool = false
				if (this.isStartLocalTool && this.AMap) {
					tool = true
				}
				return tool
			}
		},
		mounted() {
			this.initGdMaps()
		},
		methods: {
			async onChange(newValue, oldValue, ownerInstance, instance) {
				this.ownerInstance = ownerInstance
				if (!newValue) return

				const _this = this

				const mapInfo = cloneDeep(newValue)

				let rideRouteList = mapInfo.rideRouteList || []
				rideRouteList = rideRouteList.map((item) => {
					return [item.gcjLongitude, item.gcjLatitude]
				})
				this.rideRouteList = rideRouteList

				let driveRouteList = mapInfo.driveRouteList || []
				driveRouteList = driveRouteList.map((item) => {
					return [item.gcjLongitude, item.gcjLatitude]
				})
				this.driveRouteList = driveRouteList

				this.routeExtList = mapInfo.routeExtList || []
				
				this.planRouteList = mapInfo.planRouteList || []

				this.currentRecordType = this.driveRouteList.length === 0 ? "0" : "1"

				this.mapData = mapInfo

				setTimeout(function() {

					if (_this.map) {
						_this.initData();
					}
				}, 100);

			},
			async initData() {
				const _this = this

	
				_this.moveList = [..._this.rideRouteList, ..._this.driveRouteList]
				
				if(_this.mapData.isReset || _this.moveIndex > _this.moveList.length) {
					_this.carMark.stopMove()
				}
				
				console.warn("哈哈哈哈===", _this.rideRouteList.length, _this.driveRouteList.length, _this.moveList
					.length, this.moveIndex);


				if (_this.moveList.length > 0) {
					_this.initCarMark()
					_this.initStartMark()
				}

				setTimeout(() => {

					if (!_this.ridePolyline && _this.rideRouteList.length > 0) {
						_this.initPolyline(0)

					}

			
					if(_this.planRouteList.length===0) {
						if (_this.routeExtList.length > 0) {
							_this.drive(_this.routeExtList)
						}
					} else {
						_this.initPlanLine(_this.planRouteList)
					}
					
					if(_this.routeExtList.length > 0 && !_this.initTrackMarkTool) {
						_this.initTrackMarkTool = true
						_this.routeExtList.forEach((item)=> {
							_this.initTrackMark(item)
						})
					}

					setTimeout(() => {
						if (_this.moveList.length > 0) {
							console.log("isReset=====",_this.mapData.isReset)
							if (_this.moveIndex === 0) {
								_this.moveIndex = _this.moveList.length - 1
							}
							
							if(_this.mapData.isReset || _this.moveIndex > _this.moveList.length) {
								
								_this.carMark.stopMove()
								
								if(_this.timer) {
									clearTimeout(_this.timer)
									_this.timer = null
								}
								
							
								_this.moveStep = 0
								_this.movePath = []
								_this.moveIndex = _this.moveList.length - 1
								if(_this.carMark) {
									_this.carMark.setPosition(_this.moveList[_this.moveIndex]);	
								}
								
								_this.ridePolyline && _this.ridePolyline.setPath([_this.rideRouteList]);
								if(_this.currentRecordType==='0') {
									_this.drivePolyline && _this.drivePolyline.setPath([[new AMap.LngLat(0, 0)]]);
								} else {
									let lastRidePoint = []
									if(_this.rideRouteList.length>0) {
										lastRidePoint = cloneDeep(_this.rideRouteList[_this.rideRouteList.length-1])
										_this.driveRouteList.unshift(lastRidePoint)
									}
									_this.drivePolyline && _this.drivePolyline.setPath([_this.driveRouteList]);
								}
							}
							
							if (!_this.timer) {
								_this.move()
							}
							
							setTimeout(()=> {
								if (!_this.drivePolyline && _this.driveRouteList.length > 0 && _this.moveIndex > (_this.rideRouteList.length - 1)) {
									_this.initPolyline(1)
								}
							}, 100)
							
						}
					}, 500)


				}, 100);

			},
			initGdMaps() {
				if (this.AMap) return
				const _this = this
				AMapLoader.load({
					"key": "439ac54e015cff7e0c00335458361bc6", // 申请好的Web端开发者Key，首次调用 load 时必填
					"version": "2.0", // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
					"plugins": ["AMap.GraspRoad", "AMap.MoveAnimation",
						"AMap.Driving", "AMap.Geolocation", "AMap.ControlBar"
					], // 需要使用的的插件列表，如比例尺'AMap.Scale'等
				}).then((AMap) => {
					_this.AMap = AMap;
					_this.map = new AMap.Map('container', {
						zoom: 18,
						showIndoorMap: false, //隐藏地图自带的室内地图图层
						rotateEnable: true, // 地图是否可旋转
					});

					_this.graspRoad = new AMap.GraspRoad()

					_this.initData()


				}).catch(e => {
					console.log(e);
				})
			},
			initStartMark() {

				if (this.startMark) return

				let startIcon = new this.AMap.Icon({
					size: new this.AMap.Size(30, 48),
					image: 'https://oss.wanguocar.com.cn/wanguo/vms_wcl_system/images/map-start.png',
					imageSize: new AMap.Size(30, 48),
				});
				//车开始坐标
				let point = []
				if (this.moveList.length > 0) {
					point = this.moveList[0]
				}
				let marker = new this.AMap.Marker({
					position: new AMap.LngLat(point[0], point[1]),
					icon: startIcon,
					offset: new this.AMap.Pixel(-13, -48),
					zIndex: 999
				});
				this.map.add(marker);
				this.startMark = marker
			},
			initCarMark() {
				const _this = this
				if (_this.carMark) return
				const AMap = this.AMap
				let startIcon = new AMap.Icon({
					size: new AMap.Size(30, 30),
					image: 'https://oss.wanguocar.com.cn/wanguo/vms_wcl_system/images/car.png',
					imageSize: new AMap.Size(30, 30),
				});
				//车开始坐标
				let point = []
				if (this.moveList.length > 0) {
					point = this.moveList[this.moveList.length - 1]
				}
				let marker = new AMap.Marker({
					position: point,
					icon: startIcon,
					offset: new AMap.Pixel(-15, -13),
					zIndex: 9999
				});

				marker.on('moving', async function(e) {
					_this.moveListener(e)
				})

				this.map.add(marker);
				this.map.setCenter(point)

				this.carMark = marker
				
				// this.saveLog({errMsg: "定义小车车"})
				
			},
			initTrackMark(item) {
				
				let iconObj = {
					0: 'https://oss.wanguocar.com.cn/wanguo/vms_wcl_system/images/plan-start.png',
					1: 'https://oss.wanguocar.com.cn/wanguo/vms_wcl_system/images/plan-track.png',
					2: 'https://oss.wanguocar.com.cn/wanguo/vms_wcl_system/images/plan-end.png'
				}
				
				let routeType = item.routeType
				routeType = routeType === undefined ? 1: routeType
				let routeTypeIcon = iconObj[routeType]
				
				let startIcon = new this.AMap.Icon({
					size: new this.AMap.Size(30, 48),
					image: routeTypeIcon,
					imageSize: new AMap.Size(30, 48),
				});
				
				let marker = new this.AMap.Marker({
					position: new AMap.LngLat(item.longitude, item.latitude),
					icon: startIcon,
					offset: new this.AMap.Pixel(-13, -48),
					zIndex: 99
				});
				
				// this.map.add(marker)
				
				this.markerList.push(marker)
				
				console.log("他喵的====>", routeTypeIcon)
				
				if(this.markerList.length === this.routeExtList.length) {
					this.map.add(this.markerList);
				}
			},
			initPolyline(type) {
				if (!this.AMap) return
				let lineConfig = {
					path: [],
					isOutline: true,
					outlineColor: '#1FA265',
					borderWeight: 2,
					strokeColor: "#4ECC89",
					strokeWeight: 6,
					strokeOpacity: 1,
					lineJoin: 'round',
					lineCap: 'round',
					zIndex: 9999
				}

				if (type === 0) {
					lineConfig.path = this.rideRouteList
				} else {
					lineConfig.path = this.driveRouteList
					lineConfig.outlineColor = '#0F69CF'
					lineConfig.strokeColor = "#42A5FB"
				}

				let polyline = new this.AMap.Polyline(lineConfig)
				polyline.setMap(this.map)

				if (type === 0) {
					this.ridePolyline = polyline
					// let overlaysList = this.map.getAllOverlays('polyline')
					// this.map.setFitView(overlaysList)
				} else {
					this.drivePolyline = polyline
				}
			},
			move() {
				const _this = this
				if (!_this.carMark) return
				let duration = _this.duration
				_this.timer&&clearTimeout(_this.timer)
				_this.timer = setTimeout(() => {
					setTimeout(() => {
						_this.move()
					}, 100);
					
					if (_this.mapData.isReset || _this.moveIndex > _this.moveList.length - 1) {
						return _this.duration = 1000
					}
					let p = _this.moveList[_this.moveIndex++]
					
					if (!p) return _this.duration = 1000
					
					try{
						
						
						if (_this.lastMoveArr.length > 0) {
							let distance = _this.AMap.GeometryUtil.distance(_this.lastMoveArr, p)
							duration = Math.floor((distance * 1000) / 30)
							duration = duration > 6000 ? 6000 : duration
							duration = duration < 500 ? 500 : duration
							console.log("距离====>", distance, duration);
						}
						
						_this.duration = duration
					}catch(e){
						_this.saveLog({
							errMsg: '移动计算出错', 
							p, 
							moveListLength: _this.moveList.length, 
							moveIndex: _this.moveIndex,
							lastMoveArr: _this.lastMoveArr,
							lastCenterPoint: _this.lastCenterPoint
						})
					}

					try {
						_this.carMark.moveTo(p, {
							autoRotation: true,
							duration: duration,
						})

						if (_this.lastCenterPoint.length > 0) {
							let moveDistance = _this.AMap.GeometryUtil.distance(_this.lastCenterPoint, p)
							if (moveDistance > 50) {
								let moveDuration = Math.floor((moveDistance * 1000) / 20)
								console.log("moveDuration====", moveDuration)
								_this.lastCenterPoint = p
								_this.map.setCenter(p)
							}
						} else {
							_this.lastCenterPoint = p
						}
						_this.lastMoveArr = p
					} catch (e) {
						
						_this.saveLog({
							errMsg: '移动出错', 
							p, 
							moveListLength: _this.moveList.length, 
							moveIndex: _this.moveIndex,
							lastMoveArr: _this.lastMoveArr,
							lastCenterPoint: _this.lastCenterPoint
						})
						
						console.warn("move", e, p);
					}

				}, duration)
			},
			moveListener(e) {
				
				const _this = this
				
				
				if (_this.ridePolyline &&(_this.currentRecordType === '0' || (_this.currentRecordType === '1'&&_this.moveIndex < _this.rideRouteList.length))) {
					if (_this.moveStep === 0) {
						_this.movePath = _this.rideRouteList.slice(0, _this.moveIndex)
						_this.passedPolyline = _this.ridePolyline
						_this.moveStep = 1
						
					}
				
				} else {
					if (_this.drivePolyline && _this.moveStep !== 2) {
						_this.movePath = []
						if(_this.moveIndex > _this.rideRouteList.length) {
							let index = _this.moveIndex - _this.rideRouteList.length
							_this.movePath = _this.driveRouteList.slice(0, index)
						}
						_this.passedPolyline = _this.drivePolyline
						_this.moveStep = 2
					}
				}
				if (_this.passedPolyline) {
					Array.prototype.push.apply(_this.movePath, e.passedPath)
					
					_this.passedPolyline.setPath(_this.movePath);
					
				} else {
					console.warn("+++ 哈哈哈哈，找不到划线 +++");
				}
			},
			drive(routeNodes, isAll = false) {
				const _this = this
				const AMap = this.AMap
				let routerList = [];
				routeNodes.forEach((item, index) => {
					if (index != routeNodes.length - 1) {
						routerList.push([item.longitude, item.latitude, item.routeName])
					} else {
						routerList.splice(1, 0, [item.longitude, item.latitude, item.routeName])
					}
				})
				if (this.map) {
					if (this.driving && !isAll) {
						return
					}

					this.driving = new AMap.Driving({
						policy: AMap.DrivingPolicy.REAL_TRAFFIC,
						// hideMarkers: false
					});

					let waypoints = [];
					if (routerList.length > 2) {
						let router = routerList.slice(2)
						router.forEach(item => {
							waypoints.push(new AMap.LngLat(item[0], item[1]))
						})
					}
					let searchPoint = [new AMap.LngLat(routerList[0][0], routerList[0][1]), new AMap.LngLat(routerList[1][
						0
					], routerList[1][1])]
					this.driving.search(
						...searchPoint, {
							waypoints: waypoints
						},
						function(status, result) {
							// result 即是对应的驾车导航信息，相关数据结构文档请参考  https://lbs.amap.com/api/javascript-api/reference/route-search#m_DrivingResult
							if (status === 'complete') {
								try {
									let routes = result.routes || []
									if (routes.length > 0) {
										let steps = []
										routes.forEach((item) => {
											steps = [...steps, ...item.steps]
										})
										let path = []
										steps.forEach((item) => {
											path = [...path, ...item.path]
										})
										let pos = []
										path.forEach((item) => {
											pos = [...pos, [item.lng, item.lat]]
										})

										_this.initPlanLine(pos)

									}
								} catch (e) {
									//TODO handle the exception
								}
							} else {
								console.error(`🚀 - drive - result:`, result)
							}
						});
				} else {
					setTimeout(() => {
						this.drive(routeNodes, isAll)
					}, 500)
				}

			},
			initPlanLine(polylineList) {
				const _this = this
				let polyline = new this.AMap.Polyline({
					path: polylineList,
					isOutline: true,
					outlineColor: '#8793A8',
					borderWeight: 2,
					strokeColor: '#9FAAB9',
					strokeOpacity: 6,
					strokeWeight: 5,
					strokeStyle: 'solid',
					lineJoin: 'round',
					lineCap: 'round',
					// geodesic: true,
				})
				polyline.setMap(_this.map)

				setTimeout(function() {
					_this.ownerInstance && _this.ownerInstance.callMethod('uploadPlanPoint', polylineList)
				}, 2000);

			},
			onIsPhoneGpsChange(isTool, old, ownerInstance, instance) {
				console.log("+++++++++++++++++++++++++++++++++", isTool);
				const _this = this
				_this.isStartLocalTool = isTool
				if (isTool) {
					_this.ownerInstance = ownerInstance
				} else {
					_this.geolocationTimer && clearInterval(_this.geolocationTimer)
					// if(this.geolocation) {
					// 	this.geolocation.clearWatch(this.watchId)
					// }
				}
			},
			log(id, content) {
				// try {
				// 	document.getElementById(id).textContent = content
				// } catch (e) {}
			},
			currlocate() {
				try {
					if (this.moveList.length > 0) {
						const p = this.moveList[this.moveIndex - 1]
						if (!p) return
						this.map.setZoomAndCenter(18,p)
					}
				} catch (e) {
					//TODO handle the exception
				}
			},
			saveLog(logObj) {
				this.ownerInstance && this.ownerInstance.callMethod('saveErrLog', logObj)
			},
		}
	}
</script>

<style scoped lang="scss">
	.map-container {
		position: relative;
		width: 100%;
		height: 90vh;
	}

	.driving-container {
		height: 84vh;
	}
	
	.map {
		width: 100%;
		height: 100%;
	}

	.gd-map-main {
		position: relative;

		.locate-img-wrap {
			position: absolute;
			right: 15px;
			bottom: 220rpx !important;
			height: 32px;
			width: 32px;
			border-radius: 50%;
			background-color: #fff;
			display: flex;
			justify-content: center;
			align-items: center;
		}

		.locate-img {
			height: 24px;
			width: 24px;
		}
	}
	
	::v-deep .amap-icon {
		img {
			width: 100%;
			height: 100%;
		}
	}
</style>
